package com.aly.beanValidate.core;

import org.dom4j.Document;
import org.dom4j.Element;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class BeanConfigs {
    private Map<String, BeanConfig> beanDefinitionMap;

    private BeanConfigs(Document document, GlobalConfigs globalConfigs) throws Exception {
        beanDefinitionMap = initDefinition(document, globalConfigs);
    }

    public static BeanConfigs load(Document document, GlobalConfigs globalConfigs) throws Exception {
        return new BeanConfigs(document, globalConfigs);
    }

    private static Map<String, BeanConfig> initDefinition(Document document, GlobalConfigs globalConfigs) throws Exception {
        Map<String, BeanConfig> infoMap = new HashMap<>();
        for (Element element : document.getRootElement().elements()) {
            if ("models".equals(element.getName())) {
                for (Element model : element.elements()) {
                    if ("model".equals(model.getName())) {
                        String fileName = Util.attr(model, "fileName");
                        infoMap.put(fileName.toLowerCase(), new BeanConfig(new BeanDefinition(fileName, model, globalConfigs)));
                    }
                }
            }
        }
        return infoMap;
    }

    public BeanDefinition get(String fileName) {
        BeanConfig definition = beanDefinitionMap.get(fileName.toLowerCase());
        if (definition != null) {
            definition.icrUse();
            return definition.definition;
        }
        return null;
    }

    public Collection<BeanConfig> values() {
        return beanDefinitionMap.values();
    }

    public static class BeanConfig {
        private BeanDefinition definition;
        private int useCount;

        BeanConfig(BeanDefinition definition) {
            this.definition = definition;
        }

        void icrUse() {
            useCount++;
        }

        public int getUseCount() {
            return useCount;
        }

        public BeanDefinition getDefinition() {
            return definition;
        }
    }
}
